/*
 * Copyright 2007-2008 Michele Mostarda ( michele.mostarda@gmail.com ).
 * All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.asemantics.anthill;

import org.jivesoftware.smack.packet.Message;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * The response message for {@link org.asemantics.anthill.InspectCommandMessage}.
 *
 * @author Michele Mostarda
 */
public class InspectCommandResponseMessage extends CommandResponseMessage {

    /**
     * The prefix added to every message parameter to disambiaguate a target name.
     */
    public static final String TARGET_PREFIX = "target_";

    /**
     * The prefix added to every property parameter to disambiaguate a property name.
     */
    public static final String PROPERTY_PREFIX = "property_";

    /**
     * Constructor.
     *
     * @param targets
     * @param boxing if <code>true</code> the command response prepared to box parameters (server side),
     *  otherwise it is used to unbox parameters (client side).
     */
    public InspectCommandResponseMessage(Map<String,String> targets, Map<String,String> environment, boolean boxing) {
        super(Inspect.class, applyPrefixes(targets, environment), boxing);
    }

    private static Map<String, Object> applyPrefixes(final Map<String,String> targets, final Map<String,String> environment) {
        Map<String,Object> result = new HashMap<String,Object>(targets.size() + environment.size());
        for(Map.Entry<String,String> target : targets.entrySet()) {
            result.put( TARGET_PREFIX + target.getKey(), target.getValue() );
        }
        for(Map.Entry<String,String> envEntry : environment.entrySet()) {
            result.put( PROPERTY_PREFIX + envEntry.getKey(), envEntry.getValue() );
        }
        return result;
    }

    /**
     * Constructor. Invoked by introspection.
     *
     * @param targets
     */
    public InspectCommandResponseMessage( Map<String,Object> targets) {
        super(Inspect.class, targets, false);
    }

    /**
     * Returns the targets exposed by a remote listener inquired via <i>inspect</i> command.
     *
     * @param message
     * @return
     * @see InspectCommandMessage
     */
     public static Map<String,String> getTargetParameters(final Message message) {
        return getPrefixedParameters(TARGET_PREFIX, message);
     }

     /**
     * Returns the environement of the remote listener inquired via <i>inspect</i> command.
     *
     * @param message
     * @return
     * @see InspectCommandMessage
     */
     public static Map<String,String> getEnvironmentProperties(final Message message) {
        return getPrefixedParameters(PROPERTY_PREFIX, message);
     }

    /**
     * Returns a prefixed parameter collection map.
     *
     * @param prefix the prefix of the collection.
     * @param message the message from which extract the colletion.
     * @return
     */
    public static Map<String,String> getPrefixedParameters(final String prefix, final Message message) {
        Map<String,String> returnparameters = InvokeCommandResponseMessage.getReturnParameters(message);
        Collection<String> propertyNames = returnparameters.keySet();
        Map<String,String> found = new HashMap();
        for(String name : propertyNames) {
            if( name.indexOf(prefix) == 0 ) {
                found.put(name, returnparameters.get(name));
            }
        }
        returnparameters.clear();
        return found;
    }

}
